package com.duapk.search.work;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.spans.SpanNearQuery;
import org.apache.lucene.search.spans.SpanQuery;
import org.apache.lucene.search.spans.SpanTermQuery;

import com.duapk.nlp.bean.Lexeme;
import com.duapk.nlp.bean.QueryParam;
import com.duapk.nlp.bean.RewriteField;
import com.duapk.nlp.bean.RewriteResult;
import com.duapk.nlp.bean.TermInfo;
import com.duapk.nlp.constant.ChineseConstants;
import com.duapk.nlp.constant.WordType;
import com.duapk.nlp.query.QueryResource;
import com.duapk.nlp.query.QueryRewriter;
import com.duapk.search.constant.Constant;

/**
 * 查询重写
 * 
 * @Package: com.duapk.search.work
 * @ClassName: ApkQueryRewriter
 * @author: jiangzheng
 * @date: May 16, 2011 9:05:05 AM
 * 
 */
public class ApkQueryRewriter extends QueryRewriter {
	private static final int SLOP = 5;

	public ApkQueryRewriter(QueryResource resource) {
		super(resource);
	}
	
	@Override
	public BooleanQuery createQuery(List<TermInfo> termInfos,
			List<RewriteField> contentFields, QueryParam param, boolean union) {
		BooleanQuery booleanQuery = new BooleanQuery();
		BooleanQuery spanNearQuerys = new BooleanQuery();
		for (TermInfo termInfo : termInfos) {
			if (termInfo.getTerms().size() > 1) {
				Occur occur = judgeLogicOp(termInfo, union);
				if (Occur.MUST_NOT != occur && !termInfo.isSynonym()) {
					SpanNearQuery spanNearQuery = createSpanNearQuery(termInfo,
							param, occur);
					if (spanNearQuery != null) {
						spanNearQuerys.add(spanNearQuery, Occur.SHOULD);
					}
				}
				booleanQuery.add(createQuery(termInfo, param, contentFields,
						occur), occur);
			}

		}
		BooleanQuery query = null;
		if (booleanQuery.clauses().size() > 0) {
			if (spanNearQuerys.clauses().size() > 0) {
				query = new BooleanQuery();
				query.add(spanNearQuerys, Occur.SHOULD);
				query.add(booleanQuery, Occur.MUST);
			} else {
				query = booleanQuery;
			}
		}
		return query;
	}

	/**
	 * 创建查询语句
	 * 
	 * @Title: createPhraseQuery
	 * @author: jiangzheng
	 * @date: Apr 7, 2011 1:33:53 PM
	 * @return
	 */
	private SpanNearQuery createSpanNearQuery(TermInfo termInfo,
			QueryParam param, Occur occur) {
		List<Lexeme> terms = null;
		if (termInfo.isCorrect()) {
			terms = termInfo.getCorrectTerms();
		} else {
			terms = termInfo.getTerms();
		}
		if (terms.size() > 2) {
			SpanQuery[] spanQuerys = new SpanQuery[terms.size() - 1];
			for (int i = 1; i < terms.size(); i++) {
				Lexeme item = terms.get(i);
				spanQuerys[i - 1] = new SpanTermQuery(new Term(Constant.NAME,
						item.getLexemeText()));
			}

			SpanNearQuery spanNearQuery = new SpanNearQuery(spanQuerys, SLOP,
					true);
			return spanNearQuery;
		}
		return null;
	}

	public static void main(String[] args) throws IOException {
		System.setProperty(ChineseConstants.CHINESE_WORD_PATH,
				"h:/aspire/workspace/apk_nlp/models");
		QueryRewriter rewriter = new ApkQueryRewriter(QueryResource
				.getInstance());
		List<RewriteField> contentFields = new ArrayList<RewriteField>();
		contentFields.add(new RewriteField("title"));
		QueryParam param = new QueryParam();
		param.put(WordType.SYNONYM, 0.5f);
		RewriteResult result = rewriter.rewrite("angrybird", param,
				contentFields, false);
		System.out.println(result.isSuccess());
		System.out.println(result.getQuery());
		System.out.println(result.getToken());
	}
}
